package com.pai4j.remote.user;

import com.pai4j.common.bean.PAIResponseBean;
import com.pai4j.domain.vo.request.group.*;
import com.pai4j.domain.vo.response.group.*;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@FeignClient(name = "pai4j-user-service", contextId = "groupClient")
public interface GroupClient {
    /**
     * 创建或更新群组信息
     *
     * @param request 包含群组创建或更新信息的请求对象
     * @return 返回包含群组信息的响应对象
     */
    @PostMapping("/user-service/group/createOrUpdate")
    PAIResponseBean<GroupInfoResponseVO> createOrUpdate(@RequestBody CreateOrUpdateGroupRequestVO request);
    
    /**
     * 根据群组ID获取群组信息
     *
     * @param paiId 群组的唯一标识符
     * @return 返回包含群组信息的响应对象
     */
    @GetMapping("/user-service/group/get/{paiId}")
    PAIResponseBean<GroupInfoResponseVO> get(@PathVariable String paiId);
    
    /**
     * 更新群组成员设置
     *
     * @param request 包含成员设置更新信息的请求对象
     * @return 返回操作结果，true表示更新成功，false表示更新失败
     */
    @PostMapping("/user-service/group/member/setting/update")
    PAIResponseBean<Boolean> updateMemberSetting(@RequestBody UpdateGroupMemberSettingRequestVO request);
    
    /**
     * 获取指定群组中指定用户的成员设置信息
     *
     * @param groupPaiId 群组的唯一标识符
     * @param userAccount 用户账号
     * @return 返回包含用户成员设置信息的响应对象
     */
    @GetMapping("/user-service/group/member/setting/get/{groupPaiId}/{userAccount}")
    PAIResponseBean<UpdateGroupMemberSettingRequestVO> getMemberSetting(@PathVariable String groupPaiId,
                                                                        @PathVariable String userAccount);

    // ========== 群成员管理接口 ==========
    
    /**
     * 加入群聊（统一入口）
     * 智能处理加群流程：
     * - 群设置为"自由加入"：直接加入，返回 status=1
     * - 群设置为"需要审批"：自动创建审批申请，返回 status=2
     * - 群设置为"禁止加入"：拒绝加入，返回 status=5
     * - 群成员已满：返回 status=3
     * - 已在群内：返回 status=4
     * 
     * @param request 加群请求参数
     * @return JoinGroupResponseVO 包含加群结果状态码和消息
     */
    @PostMapping("/user-service/group/member/join")
    PAIResponseBean<JoinGroupResponseVO> joinGroup(@RequestBody JoinGroupRequestVO request);

    /**
     * 退出群聊
     */
    @PostMapping("/user-service/group/member/leave")
    PAIResponseBean<Boolean> leaveGroup(@RequestBody LeaveGroupRequestVO request);

    /**
     * 踢出群成员
     */
    @PostMapping("/user-service/group/member/kick")
    PAIResponseBean<Boolean> kickMembers(@RequestBody KickMemberRequestVO request);

    /**
     * 管理群成员（任命/撤销管理员、禁言/解禁、转让群主）
     */
    @PostMapping("/user-service/group/member/manage")
    PAIResponseBean<Boolean> manageGroupMember(@RequestBody ManageGroupMemberRequestVO request);

    /**
     * 获取群成员列表
     */
    @GetMapping("/user-service/group/member/list/{groupPaiId}")
    PAIResponseBean<List<GroupMemberResponseVO>> getGroupMembers(@PathVariable String groupPaiId);

    /**
     * 获取群聊当前人数
     * 
     * @param groupPaiId 群组ID
     * @return 当前群聊人数（仅统计状态正常的成员）
     */
    @GetMapping("/user-service/group/member/count/{groupPaiId}")
    PAIResponseBean<Long> getGroupMemberCount(@PathVariable String groupPaiId);

    /**
     * 获取用户加入的群聊列表
     */
    @GetMapping("/user-service/group/member/user-groups/{userAccount}")
    PAIResponseBean<List<GroupMemberResponseVO>> getUserGroups(@PathVariable String userAccount);

    /**
     * 检查用户在群内的权限
     */
    @GetMapping("/user-service/group/member/permission/{groupPaiId}/{userAccount}/{permission}")
    PAIResponseBean<Boolean> hasPermission(@PathVariable String groupPaiId,
                                          @PathVariable String userAccount,
                                          @PathVariable String permission);

    // ========== 群聊邀请接口 ==========
    
    /**
     * 邀请用户加入群聊
     */
    @PostMapping("/user-service/group/invitation/invite")
    PAIResponseBean<List<String>> inviteToGroup(@RequestBody InviteToGroupRequestVO request);

    /**
     * 处理群聊邀请（接受/拒绝）
     */
    @PostMapping("/user-service/group/invitation/handle")
    PAIResponseBean<Boolean> handleInvitation(@RequestBody HandleInvitationRequestVO request);

    /**
     * 获取用户的待处理邀请列表
     */
    @GetMapping("/user-service/group/invitation/pending/{userAccount}")
    PAIResponseBean<List<GroupInvitationResponseVO>> getPendingInvitations(@PathVariable String userAccount);

    /**
     * 获取群聊的邀请记录（分页）
     */
    @GetMapping("/user-service/group/invitation/list/{groupPaiId}")
    PAIResponseBean<Page<GroupInvitationResponseVO>> getGroupInvitations(@PathVariable String groupPaiId,
                                                                        @RequestParam(defaultValue = "0") int page,
                                                                        @RequestParam(defaultValue = "20") int size);

    // ========== 加群审批接口 ==========
    
    /**
     * 通过加群申请（强一致性）
     * 参考好友申请的confirmSubscribe设计，提供统一的审批通过接口
     * 备注为可选参数，如果提供备注则发送互动消息通知申请人
     * 
     * @param applicationId 申请ID
     * @param approverAccount 审批人账号
     * @param approvalRemark 审批备注（可选，传null表示无备注）
     * @return 是否成功
     */
    @PostMapping("/user-service/group/application/approve")
    PAIResponseBean<Boolean> approveJoinApplication(@RequestParam("applicationId") Long applicationId, 
                                                     @RequestParam("approverAccount") String approverAccount,
                                                     @RequestParam(value = "approvalRemark", required = false) String approvalRemark);
    
    /**
     * 拒绝加群申请（强一致性）
     * 参考好友申请的rejectSubscribe设计，提供统一的审批拒绝接口
     * 拒绝理由为可选参数，如果提供理由则发送互动消息通知申请人
     * 
     * @param applicationId 申请ID
     * @param approverAccount 审批人账号
     * @param approvalRemark 拒绝理由（可选，传null表示无理由）
     * @return 是否成功
     */
    @PostMapping("/user-service/group/application/reject")
    PAIResponseBean<Boolean> rejectJoinApplication(@RequestParam("applicationId") Long applicationId, 
                                                    @RequestParam("approverAccount") String approverAccount,
                                                    @RequestParam(value = "approvalRemark", required = false) String approvalRemark);
    
    /**
     * 处理加群申请（群主/管理员审批）
     * @deprecated 建议使用 approveJoinApplication 或 rejectJoinApplication 方法
     * 注意：用户加群请使用 joinGroup 方法，系统会根据群设置自动处理（直接加入或创建审批申请）
     */
    @Deprecated
    @PostMapping("/user-service/group/application/handle")
    PAIResponseBean<Boolean> handleJoinApplication(@RequestBody HandleJoinApplicationRequestVO request);

    /**
     * 获取群组的待审批申请列表（分页）
     * 仅群主和管理员可查看
     * 
     * @param groupPaiId 群组ID
     * @param requesterAccount 请求者账号（用于权限验证）
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 待审批申请列表
     */
    @GetMapping("/user-service/group/application/pending/{groupPaiId}")
    PAIResponseBean<Page<GroupJoinApplicationResponseVO>> getGroupPendingApplications(
            @PathVariable String groupPaiId,
            @RequestParam("requesterAccount") String requesterAccount,
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize);

    /**
     * 获取群组的待审批申请数量
     * 仅群主和管理员可查看
     * 
     * @param groupPaiId 群组ID
     * @param requesterAccount 请求者账号（用于权限验证）
     * @return 待审批申请数量
     */
    @GetMapping("/user-service/group/application/count/{groupPaiId}")
    PAIResponseBean<Long> getGroupPendingApplicationCount(
            @PathVariable String groupPaiId,
            @RequestParam("requesterAccount") String requesterAccount);

    /**
     * 获取用户的申请历史（分页）
     */
    @GetMapping("/user-service/group/application/history/{applicantAccount}")
    PAIResponseBean<Page<GroupJoinApplicationResponseVO>> getUserApplicationHistory(
            @PathVariable String applicantAccount,
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize);

    /**
     * 检查用户是否有待处理的申请
     */
    @GetMapping("/user-service/group/application/check/{groupPaiId}/{applicantAccount}")
    PAIResponseBean<Boolean> hasUserPendingApplication(@PathVariable String groupPaiId,
                                                       @PathVariable String applicantAccount);
}
